#include <type_traits> 
#include <iostream>
using namespace std;

namespace type_traits {

    /*
    template <class T> struct remove_cv { typedef T type; };
    template <class T> struct remove_cv<T const> { typedef T type; };
    template <class T> struct remove_cv<T volatile> { typedef T type; };
    template <class T> struct remove_cv<T const volatile> { typedef T type; };

    remove_cv

去掉变量的cv属性，获取其原始类型信息。

实现方式
模版推导丢弃const和volatile参数。

性能开销
模版推导完成操作，不涉及运行时开销。

    /// remove_const
template<typename _Tp>
struct remove_const
{ typedef _Tp     type; };

template<typename _Tp>
struct remove_const<_Tp const>
{ typedef _Tp     type; };

/// remove_volatile
template<typename _Tp>
struct remove_volatile
{ typedef _Tp     type; };

template<typename _Tp>
struct remove_volatile<_Tp volatile>
{ typedef _Tp     type; };

/// remove_cv
template<typename _Tp>
struct remove_cv
{
  typedef typename
  remove_const<typename remove_volatile<_Tp>::type>::type     type;
};
    */

    template<typename T>
    struct GetLeftSize : std::integral_constant <int, 1 >
    {
    };
   
    void main()
    {
        wcout << L"\
            std::remove_cv模板用于获取类型T，而没有const和volatile限定。\n \
            如果T不带const和volatile限定，则返回布尔值true，否则返回false。\n \
             remove_cv 这个模版类能够帮我们去掉类型的const，他的实现很简单，即使用模版元技术：\n \
            remove_cv的模版是一个T,我们对他做模版偏特化，\n \
            将const 和volatile分离，然后使用::value就可以得到没有const、volatile的类型了，\n \
            所以这个类也叫remove_cv。 \n \
            ";
        
        
        // Declare variable of type int, const 
        // int, volatile int and const volatile int 
        typedef remove_cv<int>::type A;
        typedef remove_cv<const int>::type B;
        typedef remove_cv<volatile int>::type C;
        typedef remove_cv<const volatile int&>::type D;

        cout << boolalpha << endl;

        cout << "A:is_same<const volatile int, A>"
            << is_same<const volatile int, A>::value
            << endl;

        cout << "B:is_same<const volatile int, A>"
            << is_same<const int, B>::value
            << endl;

        cout << "C:is_same<int, C>"
            << is_same<int, C>::value
            << endl;

        cout << "D:is_same<int, D>"
            << is_same<int, D>::value
            << endl;
        cout << "is_same<int&, D>:"
            << is_same<int&, D>::value
            << endl;

        B b;
        b = 10;//去掉了const

        cout << "\n\n  GetLeftSize<float>::value \n\n";
        cout << GetLeftSize<float>::value << endl;

    }
}
